<template>
  <div>
    <el-row>
      <el-col :span="5">
        <div class="bottom-container">
          <el-tree :data="data" :expand-on-click-node="false" :highlight-current="true" :props="defaultProps" default-expand-all @node-click="handleNodeClick"></el-tree>
        </div>
      </el-col>
      <el-col :span="19">
        <div class="bottom-container">
          <div style="margin: 10px">
            <el-button type="primary" @click="saveMenuData">保存</el-button>
          </div>
          <el-collapse v-model="activeNames">
            <el-collapse-item v-for="item in menuList" :key="item.id" :title="item.title" :name="item.id" >
              <el-checkbox :indeterminate="item.isIndeterminate" v-model="item.checked" @change="handleChange(item, $event)">{{item.title}}</el-checkbox>
              <div style="margin: 15px 0;"></div>
              <el-checkbox v-for="city in item.children" :label="city.id" :key="city.id" :indeterminate="city.isIndeterminate" v-model="city.checked" @change="handleChange(city, $event)">
                {{city.title}}
              </el-checkbox>
            </el-collapse-item>
          </el-collapse>
        </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
export default {
  name: 'MenuConfig',
  data () {
    return {
      data: [],
      menuList: [],
      activeNames: [],
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      isIndeterminate: true,
      checkedCities: [],
      checkAll: false,
      userId: '',
      roleId: ''
    }
  },
  created() {
    this.getRoleAndUserData()
    this.getMenuList()
  },
  methods: {
    // 保存菜单数据
    saveMenuData() {
      if (!this.userId && !this.roleId) {
        this.$message.error('需要选中角色或者人员')
      }
      const param = {
        listAuthority: this.menuList,
        userId: this.userId,
        roleId: this.roleId
      }
      this.$http.post('/frontend/api/authority/saveAuthority', param).then(res => {
        this.$message.success('保存成功')
      }).catch(errer => {
        this.$message.error(errer.message)
      })
    },
    handleNodeClick(data) {
      this.userId = data.user_id
      this.roleId = data.roleId
      this.$http.get('/frontend/api/authority/getAuthorityList', { userId: this.userId, roleId: this.roleId }).then(res => {
        this.menuList = res
      }).catch(errer => {
        this.$message.error(errer.message)
      })
    },
    getRoleAndUserData () {
      this.$http.get('/frontend/api/role/getRoleAndUser').then(res => {
        this.data = res
      }).catch(errer => {
        this.$message.error(errer.message)
      })
    },
    getMenuList () {
      this.$http.get('/frontend/api/authority/getAuthorityAll').then(res => {
        this.menuList = []
        this.activeNames = []
        this.setMenuChecked(res, false)
        res.forEach(item => {
          // 去掉隐藏的菜单
          if (!item.hidden) {
            this.menuList.push(item)
            this.activeNames.push(item.id)
          }
        })
      }).catch(errer => {
        this.$message.error(errer.message)
      })
    },
    // 复选框change事件
    handleChange(item, val) {
      // clickNum点击次数，每三次一个轮回，第一次：全选；第二次：拒绝选中；第三次：清空选中
      let mod = 0
      if (item.clickNum !== undefined) {
        const val = item.clickNum + 1
        mod = val % 3
        if (mod === 0) {
          item.isIndeterminate = false
          item.checked = false
        } else if (mod === 1) {
          item.isIndeterminate = false
          item.checked = true
        } else if (mod === 2) {
          item.isIndeterminate = true
        }
      } else {
        mod = 1
        item.clickNum = 0
        item.isIndeterminate = false
      }
      if (mod === 1) {
        const path = this.pathMenu(this.menuList, item.id)
        for (const node of path) {
          node.checked = true
          node.isIndeterminate = false
          node.clickNum = 1
        }
      }
      if (mod === 1) {
        this.setMenuChecked(item.children, true)
        this.setMenuIndeterminate(item.children, false)
      } else if (mod === 2) {
        this.setMenuChecked(item.children, false)
        this.setMenuIndeterminate(item.children, true)
      } else if (mod === 0) {
        this.setMenuChecked(item.children, false)
        this.setMenuIndeterminate(item.children, false)
      }
      item.clickNum = mod
    },
    // 初始化值
    setMenuChecked (menus, checked) {
      for (const menu of menus) {
        menu.checked = checked
        if (menu.children instanceof Array) {
          this.setMenuChecked(menu.children, checked)
        }
      }
    },
    setMenuIndeterminate (functions, checked) {
      for (const menu of functions) {
        menu.isIndeterminate = checked
        if (checked) {
          menu.clickNum = 2
        } else {
          if (menu.checked) {
            menu.clickNum = 1
          } else {
            menu.clickNum = 0
          }
        }
        if (menu.children instanceof Array) {
          this.setMenuIndeterminate(menu.children, checked)
        }
      }
    },
    pathMenu (menus, id) {
      const path = []
      const findParent = (menus, id) => {
        for (let i = 0; i < menus.length; i++) {
          const menu = menus[i]
          if (menu.id === id) {
            return true
          }
          path.push(menu)
          if (menu.children && menu.children.length > 0) {
            const contains = findParent(menu.children, id)
            if (!contains) {
              path.splice(path.findIndex((item) => item.id === menu.id), 1)
            } else {
              return true
            }
          } else {
            path.splice(path.findIndex((item) => item.id === menu.id), 1)
          }
        }
      }
      findParent(menus, id)
      return path
    }
  }
}
</script>

<style scoped>
.bottom-container {
  margin: 25px;
}
.left {
  width: 250px;
  padding: 20px;
  margin-right: 10px;
}
.right {
  padding: 10px 50px;
  flex: 1;
}
</style>
